$TITLE ('DEBUG-FUNCTIONS')
$SYMBOLS
$NOXREF
$NOCOND
$NOMOD51
$NORB
$PAGELENGTH(80) PAGEWIDTH(110)
;************************************************************************
;*									*
;*    R T X - 5 1  :  D E B U G - F U N C T I O N S                     *
;*							     		*
;*----------------------------------------------------------------------*
;*                                                                      *
;*    Filename     :   RTXDBG.A51                                       *
;*    Language     :   Keil A-51                                        *
;*    Dev. system  :   Keil uVision2                                    *
;*    Targetsystem :   Any system based upon 8051 up                    *
;*                                                                      *
;*    Purpose      :   Implements the RTX-51 Debug-Functions            *
;*								     	*
;*----------------------------------------------------------------------*
;* Rev. |  Released   | Programmer    | Comments                        *
;*----------------------------------------------------------------------*
;* 0.1  |  23.10.1991 | Th. Fischler  | Module creation                 *
;* 5.00 |  19.10.1994 | E. Glatz      | os_check_semaphore(s) added     *
;* 7.00 |  13.11.2001 | T. Mueller    | Release 7.00                    *
;************************************************************************
;*    Copyright 1991 .. 2001 METTLER  &  FUCHS  AG,  CH-8953 Dietikon   *
;************************************************************************


$INCLUDE (RTXDEBUG.INC)
$INCLUDE (RTXIMASK.INC)


;*----------------------------------------------------------------------*
;*	I M P O R T S
;*----------------------------------------------------------------------*

$INCLUDE (RTXCONST.INC)
$INCLUDE (RTXEXTRN.INC)


;*----------------------------------------------------------------------*
;*	E X P O R T S
;*----------------------------------------------------------------------*

PUBLIC _os_check_mailboxes
PUBLIC _os_check_mailbox
PUBLIC _os_check_semaphores
PUBLIC _os_check_semaphore
PUBLIC _os_check_tasks
PUBLIC _os_check_task
PUBLIC _os_check_pool


;*----------------------------------------------------------------------*
;*      C O N S T A N T S
;*----------------------------------------------------------------------*

; Tasks-state values for os_check_tasks and os_check_task
K_READY     EQU 0
K_RUNNING   EQU 1
K_BLOCKED   EQU 2
K_DELETED   EQU 3


;*----------------------------------------------------------------------*
;*	P R O C E D U R E S
;*----------------------------------------------------------------------*

;*----------------------------------------------------------------------*
;*      O S _ C H E C K _ M A I L B O X E S
;*----------------------------------------------------------------------*
;*      Get the state of all mailboxes
;*----------------------------------------------------------------------*
;*      Input:  - R6/R7 : Pointer to a table in the XDATA-space with the
;*      -----             following layout:
;*
;*                        typedef struct {
;*                                   unsigned char message_cnt;
;*                                   unsigned char read_task_count;
;*                                   unsigned char write_task_count;
;*                                } t_rtx_allmbxtab[8];
;*
;*
;*      Output: - R7 : OK
;*      ------  - table filled with the mailbox-status
;*
;*----------------------------------------------------------------------*

?RTX?_os_check_mailboxes?RTXDBG   SEGMENT CODE
                                  RSEG ?RTX?_os_check_mailboxes?RTXDBG

_os_check_mailboxes:
               DBG_SYS_ENTRY
               RTX_EXCLUDE_INT
               SETB  ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := on

               MOV   R0, #0                     ; R0 -> counter

CM_LOOP:       MOV   DPH, #HIGH(?RTX_MBX_CONTROL_BASE)
               MOV   A, R0
               SWAP  A
               RR    A
               ADD   A, #LOW(?RTX_MBX_CONTROL_BASE)
               MOV   DPL, A
               ; Check if the mailbox is empty
               MOVX  A, @DPTR                   ; A -> mbx_count
               INC   DPTR
               JNZ   NOT_EMPTY
               MOVX  A, @DPTR                   
               MOV   R3, A                      ; R3 -> mbx_tcount
               CLR   A
               MOV   R1, A                      ; no messages
               MOV   R2, A                      ; no waiting read-tasks
               JMP   FILL_TABLE

NOT_EMPTY:     ; Check if there are messages in the mailbox
               MOV   R1, A                      ; R1 -> mbx_count
               SETB  C
               XRL   A, #80H
               SUBB  A, #80H
               JC    TASKS_WAIT
               ; messages in the mailbox
               MOVX  A, @DPTR
               MOV   R3, A                      ; R3 -> mbx_tcount
               CLR   A
               MOV   R2, A                      ; no waiting tasks
               JMP   FILL_TABLE

TASKS_WAIT:    ; waiting read-tasks
               MOVX  A, @DPTR
               MOV   R3, A                      ; R3 -> mbx_tcount
               MOV   A, R1
               CPL   A
               INC   A                          ; 2's complement
               MOV   R2, A                      ; R2 -> waiting tasks
               CLR   A
               MOV   R1, A                      ; no messages

FILL_TABLE:    ; Fill the values to the xdata-table
               MOV   DPH, R6
               MOV   DPL, R7
               MOV   A, R1
               MOVX  @DPTR, A
               INC   DPTR
               MOV   A, R2
               MOVX  @DPTR, A
               INC   DPTR
               MOV   A, R3
               MOVX  @DPTR, A
               INC   DPTR
               MOV   R6, DPH
               MOV   R7, DPL
               ; Check if all mailboxes done
               INC   R0
               MOV   A, R0
               SETB  C
               SUBB  A, #07H
               JNC    CM_END
               JMP   CM_LOOP

CM_END:        MOV   R7, #OK
               CLR   ?RTX_SUPERVISOR_MODE       ; supervisor_mode := OFF
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET



;*----------------------------------------------------------------------*
;*      O S _ C H E C K _ M A I L B O X
;*----------------------------------------------------------------------*
;*      Get the state of a defined mailbox
;*----------------------------------------------------------------------*
;*      Input:  - R7    : mailbox-number
;*      -----
;*              - R4/R5 : Pointer to a table in the XDATA-space with
;*                        the following layout:
;*
;*                        typedef struct {
;*                                   unsigned char message_cnt;
;*                                   unsigned char read_task_count;
;*                                   unsigned char write_task_count;
;*                                   unsigned char wait_tasks[16];
;*                                   unsigned int messages[8];
;*                                } t_rtx_onembxtab;
;*
;*
;*      Output: - R7 : OK/NOT_OK
;*      ------  - table filled with the mailbox-status
;*
;*----------------------------------------------------------------------*

?RTX?_os_check_mailbox?RTXDBG   SEGMENT CODE
                                RSEG ?RTX?_os_check_mailbox?RTXDBG

_os_check_mailbox:
               DBG_SYS_ENTRY
               RTX_EXCLUDE_INT
               SETB  ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := on

               ; Check the mailbox-parameter
               MOV   A, R7
               SETB  C
               SUBB  A, #7H
               JC    MBX_OK
               ; input parameter not ok
               MOV   R7, #NOT_OK
               JMP   CX_END


MBX_OK:        MOV   DPH, #HIGH(?RTX_MBX_CONTROL_BASE)
               MOV   A, R7
               SWAP  A
               RR    A
               ADD   A, #LOW(?RTX_MBX_CONTROL_BASE)
               MOV   DPL, A
               ; Check if the mailbox is empty
               MOVX  A, @DPTR                   ; A -> mbx_count
               JNZ   MBX_NOT_EMPTY
               MOV   DPH, R4
               MOV   DPL, R5
               CLR   A
               MOVX  @DPTR, A                   ; table.message_count = 0
               INC   DPTR
               MOVX  @DPTR, A                   ; table.read_task_cnt = 0
               JMP   CHK_WRITE_TSK

MBX_NOT_EMPTY:  ; Check if there are messages in the mailbox
               MOV   R0, A                      ; R0 -> mbx_count
               SETB  C
               XRL   A, #80H
               SUBB  A, #80H
               JC    READ_TASKS
               ; messages in the mailbox, load mbx_first pointer
               INC   DPL
               INC   DPL
               MOVX  A, @DPTR                   ; load mbx_first
               MOV   R1, A                      ; R1 -> mbx_first
               ; Fill the table
               MOV   DPH, R4
               MOV   DPL, R5
               MOV   A, R0
               MOVX  @DPTR, A                   ; set table.message_cnt
               INC   DPTR
               CLR   A
               MOVX  @DPTR, A                   ; set table.read_task_cnt
               ; copy the messages to table.messages
               MOV   A, DPL
               ADD   A, #18
               MOV   DPL, A
               MOV   A, DPH
               ADDC  A, #0
               MOV   DPH, A                     ; DPTR -> table.messages[0]
               MOV   R2, DPH
               MOV   R3, DPL                    ; save DPTR
               MOV   B, R0                      ; set B to mbx_count

MSG_LOOP:      MOV   DPH, #HIGH(?RTX_MBX_PAGE)
               MOV   DPL, R1                    ; DPTR -> msg. in mbx
               MOVX  A, @DPTR                   ; load HIGH(message)
               MOV   R0, A
               INC   DPL
               ANL   DPL, #0EFH                 ; Increment FIFO-pointer
               MOVX  A, @DPTR                   ; Load LOW(message)
               MOV   R6, A
               INC   DPL
               ANL   DPL, #0EFH                 ; Increment FIFO-pointer
               ; Save FIFO-pointer
               MOV   R1, DPL
               ; Save the message to table.message
               MOV   DPH, R2
               MOV   DPL, R3
               MOV   A, R0
               MOVX  @DPTR, A                   ; save HIGH(message)
               INC   DPTR
               MOV   A, R6
               MOVX  @DPTR, A                   ; save LOW(message)
               INC   DPTR
               MOV   R2, DPH
               MOV   R3, DPL                    ; save DPTR
               DJNZ  B, MSG_LOOP                ; mbx_count=mbx_count-1
               JMP   CHK_WRITE_TSK

READ_TASKS:    ; waiting read-tasks
               INC   DPL
               INC   DPL
               MOVX  A, @DPTR
               MOV   R1, A                      ; R1 -> mbx_first
               ; Fill the table
               MOV   DPH, R4
               MOV   DPL, R5
               CLR   A
               MOVX  @DPTR, A                   ; set table.message_cnt
               INC   DPTR
               MOV   A, R0
               CPL   A
               INC   A                          ; 2's complement
               MOVX  @DPTR, A                   ; set table.read_task_cnt
               MOV   B, A                       ; set B to read_task_count
               ; Copy the read-task id's to the table
               INC   DPTR
               INC   DPTR                       ; DPTR -> table.wait_tasks[0]
               MOV   R2, DPH
               MOV   R3, DPL
               ; copy the task-id's to the table
R_TSK_LOOP:    MOV   DPH, #HIGH(?RTX_MBX_PAGE)
               MOV   DPL, R1                    ; DPTR -> task FIFO
               MOVX  A, @DPTR                   ; load task-id
               INC   DPL
               ANL   DPL, #0EFH
               MOV   R1, DPL                    ; save FIFO-ptr
               ANL   A, #1FH                    ; A = internal task_num
               MOV   DPH, #HIGH(?RTX_INTERNAL_NUM_TABLE)
               ADD   A, #LOW(?RTX_INTERNAL_NUM_TABLE)
               MOV   DPL, A
               MOVX  A, @DPTR                   ; Get the ext. task-num
               MOV   DPH, R2
               MOV   DPL, R3
               MOVX  @DPTR, A                   ; save ext. task-num to table
               INC   DPTR
               MOV   R2, DPH
               MOV   R3, DPL                    ; save DPTR
               DJNZ  B, R_TSK_LOOP              ; count=count-1


CHK_WRITE_TSK: MOV   DPH, #HIGH(?RTX_MBX_CONTROL_BASE)
               MOV   A, R7
               SWAP  A
               RR    A
               ADD   A, #LOW(?RTX_MBX_CONTROL_BASE)
               MOV   DPL, A
               INC   DPL                        ; DPTR -> mbx_tcount
               MOVX  A, @DPTR
               MOV   R0, A                      ; R0: mbx_tcount
               INC   DPL
               INC   DPL
               INC   DPL
               MOVX  A, @DPTR
               MOV   R1, A                      ; R1: mbx_tfirst
               MOV   DPH, R4
               MOV   DPL, R5
               INC   DPTR
               INC   DPTR
               MOV   A, R0
               MOVX  @DPTR, A                   ; set table.write_task_cnt
               JNZ   WRITE_TASKS
               ; No tasks are waiting for write
               MOV   R7, #OK
               JMP   CX_END

WRITE_TASKS:   ; waiting write-tasks
               MOV   B, R0                      ; set B to mbx_tcount
               ; Copy the write-task id's to the table
               INC   DPTR                       ; DPTR -> table.wait_tasks[0]
               MOV   R2, DPH
               MOV   R3, DPL


               ; copy the task-id's to the table
W_TSK_LOOP:    MOV   DPH, #HIGH(?RTX_MBX_PAGE)
               MOV   DPL, R1                    ; DPTR -> task FIFO
               MOVX  A, @DPTR                   ; load task-id
               INC   DPL
               ANL   DPL, #0EFH
               MOV   R1, DPL                    ; save FIFO-ptr
               ANL   A, #1FH                    ; A = internal task_num
               MOV   DPH, #HIGH(?RTX_INTERNAL_NUM_TABLE)
               ADD   A, #LOW(?RTX_INTERNAL_NUM_TABLE)
               MOV   DPL, A
               MOVX  A, @DPTR                   ; Get the ext. task-num
               MOV   DPH, R2
               MOV   DPL, R3
               MOVX  @DPTR, A                   ; save ext. task-num to table
               INC   DPTR
               MOV   R2, DPH
               MOV   R3, DPL                    ; save DPTR
               DJNZ  B, W_TSK_LOOP              ; count=count-1
               MOV   R7, #OK

CX_END:        CLR   ?RTX_SUPERVISOR_MODE       ; supervisor_mode := OFF
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET



;*----------------------------------------------------------------------*
;*      O S _ C H E C K _ S E M A P H O R E S
;*----------------------------------------------------------------------*
;*      Get the state of all semaphores.
;*----------------------------------------------------------------------*
;*      Input:  - R6/R7 : Pointer to a table in the XDATA-space with the
;*      -----             following layout:
;*
;*                        typedef struct {
;*                                   unsigned char status;
;*                                } t_rtx_allsemtab[8];
;*
;*
;*      Output: - R7 : OK
;*      ------  - table filled with the semaphore status:
;*
;*                      status = 0: token set
;*                      status = 1: token reset, no tasks wait
;*                      status = 2: token reset, tasks wait
;*
;*----------------------------------------------------------------------*

?RTX?_os_check_semaphores?RTXDBG  SEGMENT CODE
                                  RSEG ?RTX?_os_check_semaphores?RTXDBG

_os_check_semaphores:
               DBG_SYS_ENTRY
               RTX_EXCLUDE_INT
               SETB  ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := on

               MOV   R0, #0                     ; R0 = counter

CS_LOOP:       ; Check if a token is available
               MOV   A, R0
               ADD   A, #LOW(?RTX_SEM_TOKENS)
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_SEM_TOKENS) ; DPTR --> ?RTX_SEM_TOKENS[#]
               MOVX  A, @DPTR
               JNZ   TKNS_WAIT
               ; No token available: check if tasks wait
               MOV   A, R0
               SWAP  A
               RR    A
               ADD   A, #LOW(?RTX_MBX_CONTROL_BASE)
               ADD   A, #6
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_MBX_CONTROL_BASE)
               MOVX  A, @DPTR                   
               MOV   B, A                       ; B = sem_first
               INC   DPTR
               MOVX  A, @DPTR                   ; A = sem_last
               CJNE  A, B, TSKS_WAIT
               ; No token available, no tasks wait
               MOV   A, #1
               JMP   FILL_TAB

TSKS_WAIT:     ; No token available, tasks wait
               MOV   A, #2
               JMP   FILL_TAB

TKNS_WAIT:     CLR   A

FILL_TAB:      ; Fill the values to the xdata-table
               MOV   DPH, R6
               MOV   DPL, R7
               MOVX  @DPTR, A
               INC   DPTR
               MOV   R6, DPH
               MOV   R7, DPL
               ; Check if all semaphores done
               INC   R0
               MOV   A, R0
               SETB  C
               SUBB  A, #07H
               JC    CS_LOOP
               MOV   R7, #OK
               CLR   ?RTX_SUPERVISOR_MODE       ; supervisor_mode := OFF
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET



;*----------------------------------------------------------------------*
;*      O S _ C H E C K _ S E M A P H O R E
;*----------------------------------------------------------------------*
;*      Get the state of a defined semaphore.
;*----------------------------------------------------------------------*
;*      Input:  - R7    : semaphore number
;*      -----
;*              - R4/R5 : Pointer to a table in the XDATA-space with
;*                        the following layout:
;*
;*                        typedef struct {
;*                                   unsigned char token_flag;
;*                                   unsigned char task_count;
;*                                   unsigned char wait_tasks[15];
;*                                } t_rtx_onesemtab;
;*
;*
;*      Output: - R7 : OK/NOT_OK
;*      ------  - table filled with the semaphore data
;*
;*----------------------------------------------------------------------*

?RTX?_os_check_semaphore?RTXDBG SEGMENT CODE
                                RSEG ?RTX?_os_check_semaphore?RTXDBG

_os_check_semaphore:
               DBG_SYS_ENTRY
               RTX_EXCLUDE_INT
               SETB  ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := on

               ; Check the semaphore parameter
               MOV   A, R7
               JNB   ACC.3, SEM_NOTOK
               ANL   A, #0F0H
               JZ    SEM_OK
SEM_NOTOK:     MOV   R7, #NOT_OK
               JMP   CS_END
SEM_OK:        ; Check if token flag set
               MOV   A, R7
               ANL   A, #007H                   ; Convert to internal sema. no
               MOV   R7, A                      ; R7 = internal semaphore no
               ADD   A, #LOW(?RTX_SEM_TOKENS)
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_SEM_TOKENS); DPTR --> ?RTX_SEM_TOKENS[#]
               MOVX  A, @DPTR                   ; A = token flag
               ; Store token flag in result table
               MOV   DPH, R4
               MOV   DPL, R5
               MOVX  @DPTR, A                   ; Store token flag
               INC   DPTR
               INC   DPTR
               MOV   R2, DPL                    ; R2,R3 --> tab.wait_tasks[0]
               MOV   R3, DPH
               ; Search for waiting tasks  
               MOV   R0, #0                     ; R0 = task counter
               MOV   A, R7
               SWAP  A
               RR    A
               ADD   A, #LOW(?RTX_MBX_CONTROL_BASE)
               ADD   A, #6
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_MBX_CONTROL_BASE)
               MOVX  A, @DPTR                   
               MOV   B, A                       ; B = sem_first
               INC   DPTR
               MOVX  A, @DPTR                   ; A = sem_last
               XCH   A, B                       ; A = sem_first, B = sem_last
               CJNE  A, B, WTSKS                ; Check if any wait tasks
               JMP   WT_DONE
               ; Fetch wait task loop
WTSKS:         INC   R0
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_SEM_PAGE)
               MOVX  A, @DPTR                   ; Get internal task id
               ANL   A, #01FH                   ; Get internal task number
               MOV   R1, DPL                    ; R1 = old sem_first
               ; Convert internal to external task number               
               ADD   A, #LOW(?RTX_INTERNAL_NUM_TABLE)
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_INTERNAL_NUM_TABLE)
               MOVX  A, @DPTR                   ; Get the ext. task-num
               ; Store in result table
               MOV   DPL, R2
               MOV   DPH, R3
               MOVX  @DPTR, A
               INC   DPTR
               MOV   R2, DPL                    ; R2,R3 --> tab.wait_tasks[R0]
               MOV   R3, DPH
               ; Calulate new sem_first
               MOV   A, R1
               ANL   A, #00FH
               CJNE  A, #00FH, NO_WRAP
               MOV   A, R1                      ; (a) rewind ptr
               ANL   A, #0F0H
               JMP   INC_DONE
NO_WRAP:       MOV   A, R1
               INC   A                          ; (b) incr. ptr
INC_DONE:      MOV   R1, A
               CJNE  A, B, WTSKS                ; Check if more tasks
               ; Finally store wait task count
WT_DONE:       MOV   DPH, R4
               MOV   DPL, R5
               INC   DPTR
               MOV   A, R0
               MOVX  @DPTR, A                   ; Store wait task count

CS_END:        CLR   ?RTX_SUPERVISOR_MODE       ; supervisor_mode := OFF
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET


;*----------------------------------------------------------------------*
;*      O S _ C H E C K _ T A S K S
;*----------------------------------------------------------------------*
;*      Get the state of all tasks in the system
;*----------------------------------------------------------------------*
;*      Input:  - R6/R7 : Pointer to a table in the XDATA-space with the
;*      -----             following layout:
;*
;*                        typedef struct {
;*                                   unsigned char task_number;
;*                                   unsigned char state;
;*                                } t_rtx_alltasktab[19];
;*
;*                        state may be : K_READY   (0)
;*                                       K_RUNNING (1)
;*                                       K_BLOCKED (2)
;*                                       K_DELETED (3)
;*
;*      Output: - R7 : OK
;*      ------  - table filled with the task-status
;*
;*----------------------------------------------------------------------*

?RTX?_os_check_tasks?RTXDBG   SEGMENT CODE
                              RSEG ?RTX?_os_check_tasks?RTXDBG

_os_check_tasks:
               DBG_SYS_ENTRY
               RTX_EXCLUDE_INT
               SETB  ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := on

               MOV   R0, #0                     ; R0 -> task-counter

CHKT_LOOP:     MOV   DPH, #HIGH(?RTX_TID_TABLE)
               MOV   A, R0
               ADD   A, #LOW(?RTX_TID_TABLE)
               MOV   DPL, A                     ; DPTR -> tid_table[task]
               MOVX  A, @DPTR
               CJNE  A, #NIL_TID, TASK_EXISTS
               MOV   R2, #0
               MOV   R3, #K_DELETED
               JMP   CHKT_ENDL

TASK_EXISTS:   ; Evaluate the external Task-Number
               MOV   R1, A                      ; R1 -> TID
               MOV   DPH, #HIGH(?RTX_INTERNAL_NUM_TABLE)
               MOV   A, R0
               ADD   A, #LOW(?RTX_INTERNAL_NUM_TABLE)
               MOV   DPL, A
               MOVX  A, @DPTR                   ; Get the ext. task-num
               MOV   R2, A                      ; R2 -> ext. task-num
               ; Check if running task
               MOV   A, R1
               CJNE  A, ?RTX_RUNNING_TID, NOT_RUNNING
               MOV   R3, #K_RUNNING             ; R3 -> state
               JMP   CHKT_ENDL
NOT_RUNNING:   ; check if task is ready
               MOV   A, R0
               RL    A
               RL    A
               ADD   A, #LOW(?RTX_STATE_TABLE)
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_STATE_TABLE)  ; DPTR -> state_table[task]
               MOVX  A, @DPTR
               ANL   A, #0FH                    ; mask out the wait-flags
               MOV   B, A
               INC   DPL
               MOVX  A, @DPTR                   ; load the second state-byte
               ANL   A, #80H                    ; mask out the WN-Flag
               ORL   A, B
               JNZ   NOT_READY
               MOV   R3, #K_READY
               JMP   CHKT_ENDL
NOT_READY:     ; Task is blocked
               MOV   R3, #K_BLOCKED

CHKT_ENDL:     ; set the table
               MOV   DPH, R6
               MOV   DPL, R7
               MOV   A, R2
               MOVX  @DPTR, A                   ; set table.task_number
               INC   DPTR
               MOV   A, R3
               MOVX  @DPTR, A                   ; set table.state
               INC   DPTR
               MOV   R6, DPH
               MOV   R7, DPL
               INC   R0                         ; go to next task-number
               ; check if all tasks processed
               CJNE  R0, #TASK_COUNT, CHKT_LOOP

               MOV   R7, #OK
               CLR   ?RTX_SUPERVISOR_MODE       ; supervisor_mode := OFF
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET



;*----------------------------------------------------------------------*
;*      O S _ C H E C K _ T A S K
;*----------------------------------------------------------------------*
;*      Get the state of a tasks in the system
;*----------------------------------------------------------------------*
;*      Input:  - R7    : task-number
;*      -----
;*              - R4/R5 : Pointer to a table in the XDATA-space with the
;*                        following layout:
;*
;*                        typedef struct {
;*                                   unsigned char state;
;*                                   unsigned int flags;
;*                                } t_rtx_onetasktab[19];
;*
;*                        state may be : K_READY   (0)
;*                                       K_RUNNING (1)
;*                                       K_BLOCKED (2)
;*                                       K_DELETED (3)
;*
;*
;*      Output: - R7 : OK / NOT_OK
;*      ------  - table filled with the task-status
;*
;*----------------------------------------------------------------------*

?RTX?_os_check_task?RTXDBG   SEGMENT CODE
                             RSEG ?RTX?_os_check_task?RTXDBG

_os_check_task:
               DBG_SYS_ENTRY
               RTX_EXCLUDE_INT
               SETB  ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := on

               ; Check if valid tasknumber
               MOV   A, R7
               SETB  C
               SUBB  A, #?RTX_MAXTASKN
               JC    EVAL_INTERNAL_NUM
               ; Number is greater than the maximum used task-number
               MOV   R7, #NOT_OK
               JMP   CHK_TSK_END

EVAL_INTERNAL_NUM:
               ; Evaluate the internal Task-Number
               MOV   DPH, #HIGH(?RTX_USER_NUM_TABLE)
               MOV   A, #LOW(?RTX_USER_NUM_TABLE)
               ADD   A, R7
               MOV   DPL, A
               ; DPTR -> user_num_table[user_num]
               MOVX  A, @DPTR
               ; Check if valid task
               CJNE  A, #NO_TASK, TASK_FOUND
               ; No Task
               MOV   R1, #K_DELETED
               MOV   R2, #0
               MOV   R3, #0
               JMP   SET_TABLE

TASK_FOUND:    ; valid task
               MOV   R0, A                      ; R0 -> internal task-nbr.
               ; Load the state-flags
               RL    A
               RL    A
               ADD   A, #LOW(?RTX_STATE_TABLE)
               MOV   DPL, A
               MOV   DPH, #HIGH(?RTX_STATE_TABLE)  ; DPTR -> state_table[task]
               MOVX  A, @DPTR
               MOV   R2, A                      ; R2 -> wait-flags
               INC   DPL
               MOVX  A, @DPTR                   ; load the second state-byte
               ANL   A, #80H                    ; mask out the WN-Flag
               MOV   R3, A                      ; R3 -> wait-flags

               ; Check if running task
               MOV   DPH, #HIGH(?RTX_TID_TABLE)
               MOV   A, R0
               ADD   A, #LOW(?RTX_TID_TABLE)
               MOV   DPL, A                     ; DPTR -> tid_table[task]
               MOVX  A, @DPTR
               CJNE  A, ?RTX_RUNNING_TID, TSK_NOT_RUN
               MOV   R1, #K_RUNNING             ; R1 -> state
               JMP   SET_TABLE

TSK_NOT_RUN:   MOV   A, R2
               ORL   A, R3
               JNZ   TSK_NOT_READY
               MOV   R1, #K_READY
               JMP   SET_TABLE

TSK_NOT_READY: MOV   R1, #K_BLOCKED

SET_TABLE:     ; Set the table
               MOV   DPH, R4
               MOV   DPL, R5
               MOV   A, R1
               MOVX  @DPTR, A                   ; set table.state
               ; set table.flags
               INC   DPTR
               MOV   A, R2
               ANL   A, #80H                    ; extract the SR-flag
               RL    A
               MOVX  @DPTR, A                   ; set High-byte of flags
               INC   DPTR
               MOV   A, R3
               MOV   C, ACC.7                   ; Load the WN-flag
               MOV   A, R2
               RL    A
               MOV   ACC.0, C
               MOVX  @DPTR, A                   ; set the Low-byte of flags
               MOV   R7, #OK

CHK_TSK_END:   CLR   ?RTX_SUPERVISOR_MODE       ; supervisor_mode := OFF
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET




;*----------------------------------------------------------------------*
;*      O S _ C H E C K _ P O O L
;*----------------------------------------------------------------------*
;*      Get infos about a memory-pool
;*----------------------------------------------------------------------*
;*      Input:  - R6/R7 : block-size of the pool
;*      -----
;*              - R4/R5 : Pointer to a table in the XDATA-space with the
;*                        following layout:
;*
;*                        typedef struct {
;*                                   void xdata *block;
;*                                   unsigned char task_number;
;*                                } t_rtx_blockinfo[255];
;*
;*
;*      Output: - R7 : OK / NOT_OK
;*      ------  - table filled with the task-status
;*
;*----------------------------------------------------------------------*

?RTX?_os_check_pool?RTXDBG   SEGMENT CODE
                             RSEG ?RTX?_os_check_pool?RTXDBG

_os_check_pool:
               DBG_SYS_ENTRY
               RTX_EXCLUDE_INT
               SETB  ?RTX_SUPERVISOR_MODE       ; Supervisor_mode := on

               MOV   A, R7
               ORL   A, R6
               JNZ   CP_INP_OK
               MOV   R7, #NOT_OK
               JMP   CP_END

CP_INP_OK:     ; Search the coresponding pool-control structure
               ; The pool-control structures are inpage-allocated!
               MOV   R0, #0                     ; R0 -> contr.-struct. counter
               MOV   DPTR, #?RTX_POOL_CONTR
CP_LOOP:       MOVX  A, @DPTR                   ; check block_size
               XRL   A, R6
               JNZ   NEXT_CONT                  ; block-size is not equal
               INC   DPL
               MOVX  A, @DPTR
               XRL   A, R7
               JNZ   NEXT_CONT                  ; block-size is not equal

               ; pool-control structure found, load the pool_ptr
               ; and the number of blocks
               INC   DPL
               MOVX  A, @DPTR
               MOV   R1, A
               INC   DPL
               MOVX  A, @DPTR
               MOV   R2, A                      ; R1/R2 holds the pool_ptr
               INC   DPL
               INC   DPL
               MOVX  A, @DPTR
               MOV   R3, A                      ; R3 holds the nbr_of_blocks
               JMP   POOL_FOUND

NEXT_CONT:    ; go to the next pool-control struct
               INC   R0
               MOV   A, R0
               SETB  C
               SUBB  A, #0FH
               JNC   NOT_FOUND     ; No coresponding pool-contr. struct. found
               MOV   A, R0
               MOV   B, #06H
               MUL   AB
               ADD   A, #LOW(?RTX_POOL_CONTR)
               MOV   DPL, A
               JMP   CP_LOOP

NOT_FOUND:     MOV   R7, #NOT_OK
               JMP   CP_END
               
POOL_FOUND:    ; R1/R2 holds the pool_ptr (pool start address)
               ; R3 holds the number of blocks

               ; set table to zero
               MOV   R0, #255
               MOV   DPH, R4
               MOV   DPL, R5
               CLR   A
CLR_L:         MOVX  @DPTR, A
               INC   DPTR
               MOVX  @DPTR, A
               INC   DPTR
               MOVX  @DPTR, A
               INC   DPTR
               DJNZ  R0, CLR_L

               ; block_size = block_size + 2
               MOV   A, R7
               ADD   A, #2
               MOV   R7, A
               MOV   A, R6
               ADDC  A, #00
               MOV   R6, A

               ; set the table
SET_L:         MOV   DPH, R1
               MOV   DPL, R2
               INC   DPTR
               MOVX  A, @DPTR
               CJNE  A, #NIL_TID, BLOCK_USED
               JMP   NEXT_BLOCK
BLOCK_USED:    ANL   A, #1FH                    ; A = internal task_num
               MOV   DPH, #HIGH(?RTX_INTERNAL_NUM_TABLE)
               ADD   A, #LOW(?RTX_INTERNAL_NUM_TABLE)
               MOV   DPL, A
               MOVX  A, @DPTR                   ; Get the ext. task-num
               MOV   R0, A                      ; R0 holds the ext. task-num
               ; save the values to the table
               MOV   DPH, R1
               MOV   DPL, R2
               INC   DPTR
               INC   DPTR
               MOV   A, DPH
               MOV   B, DPL                     ; A/B holds the block-adr.
               MOV   DPH, R4
               MOV   DPL, R5
               MOVX  @DPTR, A                   ; save the block-ptr
               INC   DPTR
               MOV   A, B
               MOVX  @DPTR, A
               INC   DPTR
               MOV   A, R0
               MOVX  @DPTR, A                   ; save the task-number
               INC   DPTR
               MOV   R4, DPH                    ; save the table-ptr
               MOV   R5, DPL

NEXT_BLOCK:    ; go to the next block
               MOV   A, R2
               ADD   A, R7
               MOV   R2, A
               MOV   A, R1
               ADDC  A, R6
               MOV   R1, A
               ; Check if all block processed
               DJNZ  R3, SET_L
               MOV   R7, #OK

CP_END:        CLR   ?RTX_SUPERVISOR_MODE       ; supervisor_mode := OFF
               DBG_SYS_EXIT
               RTX_ALLOW_INT
               RET


;
;   END OF MODULE
;
	END


